package lib.toolbar.widget;

import android.content.Context;
import android.graphics.Color;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;

import hd.util.ScreenHelper;
import hd.util.ViewAnimation;
import hd.util.app.BaseContext;

/**
 * Sidebar
 * 侧边栏
 * <p/>
 * Created by Haidy on 15/3/3.
 */
public class SideBarView extends ViewGroup {

    //    public static final String TAG = "SidebarView";
    private static final int MAX_VELOCITY = 1000;

    private RelativeLayout sidebarView;
    private RelativeLayout contentView;

    private ViewAnimation animation;            //动画工具

    private int sidebarWidth = 150;             //距离右边为100dp，限制最宽为320dp
    private int minSidebarMove = 5;             //dp
    public final int MAX_SIDEBAR_WIDTH = ScreenHelper.dp2px(getContext(), 320);
    private boolean isScroll = false;           //是否正在滑动
    private boolean canScroll = false;          //是否可以滑动
    private VelocityTracker mVelocityTracker;   //管理滑动速度
    private boolean open = false;

    private float startX;
    private float startY;
    private float touchWidth = 15;              //dp，手指触摸边沿的宽度
    private View blackView;
    private float blackVelocity;
    private OnStatueChangeListener onStatueChangeListener;

    private BaseContext baseContext;

    public SideBarView(Context context) {
        this(context, null);
    }

    private SideBarView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    private SideBarView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        baseContext = (BaseContext) context.getApplicationContext();
        init();
    }

    /**
     * 初始化
     */
    private void init() {
        initData();
        initView();
    }

    /**
     * 初始化一部分数据
     */
    private void initData() {
        // 侧边栏的宽度
        sidebarWidth = baseContext.getScreenWidth() - ScreenHelper.dp2px(getContext(), sidebarWidth);
        sidebarWidth = sidebarWidth > MAX_SIDEBAR_WIDTH ? MAX_SIDEBAR_WIDTH : sidebarWidth;
        // 触摸边沿宽度
        touchWidth = ScreenHelper.dp2px(getContext(), touchWidth);
        // 初始化其他
        animation = new ViewAnimation();
        animation.setOnAnimationListener(animationListener);
        blackVelocity = 100f / sidebarWidth;//计算黑暗的速率
        minSidebarMove = ScreenHelper.dp2px(getContext(), minSidebarMove);
    }

    /**
     * 滑动监听
     */
    private ViewAnimation.OnAnimationListener animationListener = new ViewAnimation.OnAnimationListener() {
        @Override
        public void onAnimationStart() {
            isScroll = true;
            if (blackView.getVisibility() == GONE) {
                blackView.setVisibility(VISIBLE);
            }
        }

        @Override
        public void onScrollTo(int pixelX, int pixelY) {
            onViewChange(pixelX);
        }

        @Override
        public void onAnimationStop() {
            isScroll = false;
            int scrollX = sidebarView.getScrollX();
            if (scrollX == 0) {
                open = true;
            } else if (scrollX == sidebarWidth) {
                open = false;
                blackView.setVisibility(GONE);
            }
            if (onStatueChangeListener != null) {
                onStatueChangeListener.onChange(open);
            }
//            Log.d(TAG, open + "");
        }
    };

    /**
     * 初始化界面
     */
    private void initView() {
        // 添加SidebarView和ContentView
        contentView = new RelativeLayout(getContext());
        sidebarView = new RelativeLayout(getContext());
        LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        addView(contentView, lp);
        addView(blackView = new View(getContext()), lp);
        addView(sidebarView, lp);
        sidebarView.scrollTo(sidebarWidth, 0);
    }

    private int distanceToLeft;// 手指到左边的距离

    @Override
    public boolean onTouchEvent(@NonNull MotionEvent event) {
        int x = (int) event.getX();
        obtainVelocityTracker(event);
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
//                Log.d(TAG + "_onTouch", "DOWN");
                //记录手指位置
                distanceToLeft = x + sidebarView.getScrollX();
                break;
            case MotionEvent.ACTION_MOVE:
//                Log.d(TAG + "_onTouch", "MOVE_X = " + sidebarView.getScrollX());
                if (canScroll) {
                    if (blackView.getVisibility() == GONE) {
                        blackView.setVisibility(VISIBLE);
                    }
                    distanceToLeft = distanceToLeft == 0 ? x + sidebarView.getScrollX() : distanceToLeft;
                    if (sidebarView.getScrollX() <= sidebarWidth && sidebarView.getScrollX() >= 0) {//可滑动范围
                        int moveToX = distanceToLeft - x;
                        moveToX = moveToX < 0 ? 0 : (moveToX > sidebarWidth ? sidebarWidth : moveToX);
                        sidebarView.scrollTo(moveToX, 0);
                        onViewChange(moveToX);
                    } else {
                        distanceToLeft = 0;
                        canScroll = false;
                    }
                } else {
                    if (!isScroll && open && Math.abs(startX - x) > 30 && x <= sidebarWidth) {
                        distanceToLeft = 0;
                        canScroll = true;
                    }
                }
                break;
            case MotionEvent.ACTION_UP:
//                Log.d(TAG + "_onTouch", "UP");
                if (canScroll) {
                    if (animation.isScrolling()) {
                        animation.stopScrolling();
                    }
                    mVelocityTracker.computeCurrentVelocity(1000);
                    int velocity = (int) mVelocityTracker.getXVelocity();
                    if (velocity > 0 && MAX_VELOCITY < velocity) {//速度
                        open(velocity);
                    } else if (velocity < 0 && MAX_VELOCITY < -velocity) {//速度
                        close(velocity);
                    } else if (sidebarWidth - sidebarView.getScrollX() > baseContext.getScreenWidth() / 3) {//缓慢
                        open(velocity);
                    } else {//缓慢
                        close(velocity);
                    }
                } else {
                    if (open && x >= sidebarWidth && x - startX <= minSidebarMove && event.getY() - startY <= minSidebarMove) {
                        close(0);
                    }
                }
                canScroll = false;
                distanceToLeft = 0;
                releaseVelocityTracker();
                break;
        }
        return true;
    }

    /**
     * 关闭侧边栏
     *
     * @param velocity 速度
     */
    private void close(int velocity) {
        int startX = sidebarView.getScrollX();
        int dx = sidebarWidth - startX;
        animation.setDuration(getScrollTime(velocity, dx));
        animation.startAnimation(sidebarView, startX, 0, dx, 0);
    }

    /**
     * 打开侧边栏
     *
     * @param velocity 速度
     */
    private void open(int velocity) {
        int startX = sidebarView.getScrollX();
        int dx = -startX;
        animation.setDuration(getScrollTime(velocity, dx));
        animation.startAnimation(sidebarView, startX, 0, dx, 0);
    }

    /**
     * 获取滑动的时间
     *
     * @param velocity 速度
     * @param dx       距离
     * @return time
     */
    private int getScrollTime(int velocity, int dx) {
        int maxTime = 500;
        int minTime = 100;
        velocity = velocity == 0 ? minTime : velocity;
        int time = Math.abs(dx * 1500 / velocity);
        time = time < minTime ? minTime : time;
        time = time > maxTime ? maxTime : time;
        return time;
    }

    /**
     * 实时改变的
     *
     * @param scrollToX 滑动到得X坐标的
     */
    private void onViewChange(int scrollToX) {
        isScroll = true;
        int showWidth = sidebarWidth - scrollToX;
        blackView.setBackgroundColor(Color.argb((int) (showWidth * blackVelocity), 0, 0, 0));
        blackView.invalidate();
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        float x = ev.getX();
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                startX = x;
                startY = ev.getY();
                if (animation.isScrolling() && x <= sidebarWidth - sidebarView.getScrollX()) {
                    animation.stopScrolling();
                    return canScroll = true;
                }
                if (!animation.isScrolling() && (!open && x <= touchWidth)) {
//                    Log.d(TAG, "start TOUCH open");
                    return canScroll = true;
                }
//                Log.d(TAG + "_Intercept", "DOWN");
                break;
            case MotionEvent.ACTION_MOVE:
//                Log.d(TAG + "_Intercept", "MOVE");
                if (open && Math.abs(startX - x) > 30 && x <= sidebarWidth) {
                    return canScroll = true;
                }
                if (open && x >= sidebarWidth) {
                    return true;
                }
                break;
            case MotionEvent.ACTION_UP:
//                Log.d(TAG + "_Intercept", "UP");
                releaseVelocityTracker();
                break;
        }
        return super.onInterceptTouchEvent(ev);
    }

    private void obtainVelocityTracker(MotionEvent event) {
        if (mVelocityTracker == null) {
            mVelocityTracker = VelocityTracker.obtain();
        }
        mVelocityTracker.addMovement(event);
    }

    private void releaseVelocityTracker() {
        if (mVelocityTracker != null) {
            mVelocityTracker.recycle();
            mVelocityTracker = null;
        }
    }

    /**
     * 设置ContentView
     *
     * @param contentView view
     */
    public void setContentView(View contentView) {
        this.contentView.removeAllViews();
        this.contentView.addView(contentView);
    }

    /**
     * 设置SidebarView
     *
     * @param sidebarView view
     */
    public void setSidebarView(View sidebarView) {
        this.sidebarView.removeAllViews();
        this.sidebarView.addView(sidebarView);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        contentView.layout(0, 0, baseContext.getScreenWidth(), contentView.getMeasuredHeight());
        blackView.layout(0, 0, baseContext.getScreenWidth(), blackView.getMeasuredHeight());
        sidebarView.layout(0, 0, sidebarWidth, sidebarView.getMeasuredHeight());
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);

        setMeasuredDimension(width, height);
        contentView.measure(widthMeasureSpec, heightMeasureSpec);
        blackView.measure(widthMeasureSpec, heightMeasureSpec);
        sidebarView.measure(MeasureSpec.makeMeasureSpec(sidebarWidth, MeasureSpec.getMode(widthMeasureSpec)), heightMeasureSpec);
    }

    /**
     * 监听侧边栏事件
     *
     * @param onStatueChangeListener 回调接口
     */
    public void setOnStatueChangeListener(OnStatueChangeListener onStatueChangeListener) {
        this.onStatueChangeListener = onStatueChangeListener;
    }

    /**
     * 获取sidebarView
     *
     * @return sidebarView
     */
    public View getSidebarView() {
        return sidebarView;
    }

    /**
     * 打开侧边栏
     */
    public void open() {
        open(8000);
    }

    /**
     * 关闭侧边栏
     */
    public void close() {
        close(8000);
    }

    /**
     * 是否打开
     *
     * @return open
     */
    public boolean isOpen() {
        return open;
    }

    public interface OnStatueChangeListener {

        void onChange(boolean open);
    }
}
